package com.life.ai.server.common.domain;

import cn.hutool.json.JSONUtil;
import com.life.ai.server.common.exception.AbstractException;
import com.life.ai.server.common.exception.errorcode.BaseErrorCode;
import com.life.ai.server.common.exception.errorcode.IErrorCode;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

import java.io.Serializable;

/**
 * R
 * 响应信息主体
 *
 * @author kylewka
 * @since 2023/8/28
 */
@Data
@Accessors(chain = true)
@NoArgsConstructor
public class R<T> implements Serializable {
    private static final long serialVersionUID = 1L;

    /**
     * 正确返回码
     */
    public static final String SUCCESS_CODE     = "000000";
    public static final String SUCCESS_CODE_MSG = "success";


    @ApiModelProperty(value = "结果代码", position = 1)
    private String code;

    @ApiModelProperty(value = "错误信息", position = 2)
    private String msg;

    @ApiModelProperty(value = "结果数据", position = 3)
    private T data;

    public static <T> R<T> ok() {
        return restResult(SUCCESS_CODE, SUCCESS_CODE_MSG, null);
    }

    public static <T> R<T> ok(T result) {
        return restResult(SUCCESS_CODE, SUCCESS_CODE_MSG, result);
    }

    public static <T> R<T> ok(T result, String msg) {
        return restResult(SUCCESS_CODE, msg, result);
    }

    public static <T> R<T> fail() {
        BaseErrorCode errorCode = BaseErrorCode.SERVICE_ERROR;
        return restResult(errorCode.getCode(), errorCode.getMessage(), null);
    }

    public static <T> R<T> fail(String message) {
        return restResult(BaseErrorCode.SERVICE_ERROR.getCode(), message, null);
    }

    public static <T> R<T> fail(IErrorCode errorCode) {
        return restResult(errorCode.getCode(), errorCode.getMessage(), null);
    }

    public static <T> R<T> fail(AbstractException exception) {
        return restResult(exception.getErrorCode(), exception.getMessage(), null);
    }

    public static <T> R<T> fail(IErrorCode code, String message) {
        message = message == null ? code.getMessage() : message;
        return restResult(code.getCode(), message, null);
    }

    public static <T> R<T> fail(String codeValue, String message) {
        return restResult(codeValue, message, null);
    }

    private static <T> R<T> restResult(String code, String message, T data) {
        R<T> result = new R<>();
        result.setCode(code);
        result.setMsg(message);
        result.setData(data);
        return result;
    }

    public String toJson() {
        return JSONUtil.toJsonStr(this);
    }
}